var gulp = require('gulp')
var typescript = require('gulp-typescript')
var sourcemaps = require('gulp-sourcemaps')
var webpack = require('webpack-stream')
var rimraf = require('rimraf')
var path = require('path')
var tsconfig = require('./tsconfig.json') 

const BASE_DIR = path.join(__dirname, 'src')
const DIST_DIR = 'dist'

function watch(sources, tasks) {
  gulp.watch(sources, {
    debounceDelay: 20,
    mode: 'auto',
    cwd: __dirname
  }).on('change', function (e) {
    var now = new Date()
    var time = now.getHours() + ':' + now.getMinutes() + ':' + now.getSeconds()
    var pathname = path.relative(process.cwd(), e.path)
    console.log('[\033[90m' + time + '\033[0m] ' + pathname + 
                ' was \033[35m' + e.type + '\033[0m')
    gulp.start.apply(gulp, tasks)
  })
}

function compileMain(pathname) {
  return function () {
    return gulp
            .src(pathname, {
              base: BASE_DIR
            })
            .pipe(sourcemaps.init())
            .pipe(typescript(tsconfig.compilerOptions))
            .pipe(sourcemaps.write('.'))
            .pipe(gulp.dest('dist'))
  }
}

function compileComponents(pathname) {
  return function () {
    var ws = webpack({
      output: {
        filename: path.join(path.dirname(pathname).replace(/^\.?\/?src\/?/, ''), path.basename(pathname, '.tsx') + '.js')
      },
      externals: [
        {
          'react': 'React',
          'react-dom': 'ReactDOM',
          'react-router': 'ReactRouter',
          'react-channel': 'ReactChannel'
        }
      ],
      resolve: {
        extensions: ['', '.tsx'],
      },
      module: {
        loaders: [
          { 
            test: /\.tsx$/, 
            loader: "ts-loader",
            exclude: /node_modules/
          }
        ]
      }
    }).on('error', function (error) {
      console.error(error.toString())
      this.emit('end')
    })
    return gulp
            .src(pathname, {
              base: BASE_DIR
            })
            .pipe(sourcemaps.init())
            .pipe(ws)
            .pipe(sourcemaps.write('.'))
            .pipe(gulp.dest(DIST_DIR))
  }
}

function clearDist(dirname) {
  return function () {
    rimraf.sync(path.join(DIST_DIR, dirname))
  }
}

gulp.task('copy', function () {
  return gulp
          .src(['src/**/*.!(tsx|ts)'], {
            base: BASE_DIR
          })
          .pipe(gulp.dest("dist"))
})
gulp.task('components', compileComponents('src/components/index.tsx'))
gulp.task('main', compileMain('src/**/*.ts'))
gulp.task('watchfiles', function () {
  watch(['src/**/*.!(tsx|ts)'], ['copy'])
  watch(['src/**/*.tsx'], ['components'])
  watch(['src/**/*.ts'], ['main'])
})
gulp.task('clear', clearDist('.'))
gulp.task('build', ['clear', 'copy', 'components', 'main'])
gulp.task('watch', ['clear', 'copy', 'components', 'main', 'watchfiles'])